<template>
  <div class="chart-box">
    <el-row class="line-row" v-loading="chartLoading">
      <div class="tip-box" v-show="showTip" v-html="lineContent"></div>
      <chart
        @chartclick="getItemData"
        style="width: 100%; height: 100%"
        :option="lineOption"
        ref="lineChart"
        auto-resize
        @legendselectchanged="legendselectchanged"
      ></chart>
    </el-row>
  </div>
</template>

<script>
import nt from '../../../../../network'
import parseApi from '../../../../utils/parseApi'
 import _ from 'lodash'
import mixinOption from '../../../../utils/mixinOption'
export default {
  name: 'custom-report-component-chart-line',
  props: {
    api: {},
    method: {
      type: String,
      default: 'get',
    },
    dataKey: {},
    mainTitle: {},
    time: {},
    componentData: {},
    changeSize: {},
    changeData: {},
    interval: {},
    mixinParam: {
      type: Object,
      default() {
        return {}
      },
    },
  },
  computed: {
    lineOption() {
      switch (this.dataKey) {
        case 'common':
          return this.commonLineOption
          break
      }
    },
  },
  data() {
    return {
      timer: null,
      visible: false,
      unit: '', // { seriesName: unit }
      showTip: false,
      lineContent: '',
      comInterval: 0,
      showMore: false,
      chartLoading: false,
      isDataReady: false,
      barRate: 0.2,
      section: '', // 统计区间 每日-12、每周-7、每月-12
      sectionType: '', // 查询日/周/月
      seriesTypeList: [],
      yAxisUnit: [], // Y轴单位
      dataUnit: [], // 缓存曲线原始数据单位 ['%', '%', '%', '%']
      seriesYAxisIndexList: [], // 曲线Y轴索引
      commonLineData: {
        tooltip: {
          trigger: 'axis',
          extraCssText: 'text-align:left;',
          position: function (point, params, dom, rect, size) {
            if (point[0] > size.viewSize[0] / 2) {
              return [point[0] - size.contentSize[0] - 30, '10%']
            } else {
              return [point[0] + 30, '10%']
            }
          },
        },
        grid: {
          left: '50px',
          right: '20px',
          top: '30px',
          bottom: '20px',
        },
        calculable: true,
        legend: {
          show: true,
          type: 'scroll',
          orient: 'horizontal',
          pageIconColor: '#aaa',
          pageIconInactiveColor: '#ddd',
          top: 'top',
          left: 'right',
          itemWidth: 9,
          itemHeight: 9,
          textStyle: {
            fontSize: '12',
            fontFamily: 'PingFangSC-Regular',
            color: '#6D7C8B',
          },
          selected: {},
          data: [],
          // icon: 'circle',
          formatter: function (name) {
            // if (!name) return ''
            // if (name.length > 10) {
            //   name = name.slice(0, 10) + '...'
            //   return name
            // } else {
            return name
            // }
          },
          tooltip: {
            show: true,
          },
        },
        color: ['#25CCA7', '#F7A54C', '#419EFF', '#F46E6E', '#3581D1'],
        xAxis: [
          {
            show: true,
            type: 'category',
            boundaryGap: false,
            data: [],
            axis: {
              show: true,
            },
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              rotate: 0,
              interval: 'auto',
              textStyle: {
                fontFamily: 'PingFangSC-Regular',
                fontSize: '12',
                color: '#526476',
              },
            },
          },
        ],
        yAxis: [
          {
            show: true,
            type: 'value',
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              rotate: 0,
              textStyle: {
                fontFamily: 'PingFangSC-Regular',
                fontSize: '12',
                color: '#526476',
              },
            },
            splitLine: {
              show: true,
              lineStyle: {
                color: ['#F1F1F1'],
              },
            },
            splitNumber: 4,
          },
        ],
        series: [],
      },
      commonLineOption: {},
      yAxisObj: {
        show: true,
        type: 'value',
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          textStyle: {
            fontFamily: 'PingFangSC-Regular',
            fontSize: '12',
            color: '#526476',
          },
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: ['#F1F1F1'],
          },
        },
        splitNumber: 4,
      },
    }
  },
  watch: {
    componentData() {
      this.changeStyle()
    },
    changeSize() {
      this.$refs.lineChart.resize()
    },
    'api.dsName': function () {
      this.getCommonLineData(this.changeStyle, true)
    },
    time() {
      this.changeParam()
    },
    mixinParam: {
      handler: function (val, oldVal) {
        let int = 0
        int = setInterval(() => {
          if (!this.chartLoading) {
            clearInterval(int)
            this.changeParam()
          }
        }, 50)
      },
      deep: true,
    },
  },
  methods: {
    legendselectchanged: function (param) {
      if (this.dataKey !== 'common') return
      let selecteds = param.selected
      let selectedName = param.name
      let all = true
      for (let o in selecteds) {
        all = all && !selecteds[o]
      }
      for (let o in selecteds) {
        if (all) {
          this.commonLineData.legend.selected[o] = true
        }
        if (selectedName === o && !all) {
          this.commonLineData.legend.selected[o] = true
        }
        if (selectedName != o && !all) {
          this.commonLineData.legend.selected[o] = false
        }
      }
    },
    changeParam() {
      if (this.api) {
        this.getCommonLineData(this.changeStyle)
        clearInterval(this.comInterval)
        if (this.interval) {
          this.comInterval = setInterval(() => {
            this.getCommonLineData(this.changeStyle)
          }, this.interval * 1000)
        }
      }
    },
    getCommonLineData(callback, newApi) {
      this.chartLoading = true
      let parseLineData = (data) => {
        if (!data.valueList || !data.valueList.length) {
          data = {
            valueList: [
              //纵轴数据
              {
                //每一项是每条线的数据
                name: '', //右上角tooltip展示和每条线鼠标悬浮展示字
                value: [
                  {
                    data: 0, //线上点高度
                    name: '', //对应横坐标label
                    unit: '', //data后单位
                  },
                ],
              },
            ],
          }
        }
        if (data.valueList) {
          let xData = data.valueList[0]
            ? data.valueList[0].value.map((item) => item.name)
            : []
          let yData = data.valueList
          let commonLineData = this.commonLineData
          if (!this.componentData.seriesTypeList || newApi) {
            this.componentData['seriesTypeList'] = data.valueList.map(
              (item) => false
            )
          }

          this.unit = {}
          let unit =
            data.valueList[0] &&
            data.valueList[0].value &&
            data.valueList[0].value[0]
              ? data.valueList[0].value[0].unit || ''
              : ''
          let tmpUnit
          this.yAxisUnit = []
          this.dataUnit = []
          if (!this.componentData.seriesYAxisIndexList || newApi) {
            let seriesYAxisIndexList
            // 判断后台返回数据单位是否一样
            seriesYAxisIndexList = []
            data.valueList.forEach((item) => {
              tmpUnit =
                item.value && item.value[0] ? item.value[0].unit || '' : ''
              // 设置曲线Y轴索引
              seriesYAxisIndexList.push(unit === tmpUnit ? 0 : 1)
              this.yAxisUnit.indexOf(tmpUnit) === -1 &&
                this.yAxisUnit.push(tmpUnit)
            })

            this.componentData['seriesYAxisIndexList'] = seriesYAxisIndexList

            // 只有一个Y轴
            if (this.yAxisUnit.length === 1) {
              commonLineData.yAxis.length > 1 && commonLineData.yAxis.pop()
              this.componentData.yAxis = JSON.parse(
                JSON.stringify([this.componentData.yAxis[0]])
              )
            } else {
              commonLineData.yAxis.length === 1 &&
                commonLineData.yAxis.push(commonLineData.yAxis[0])
              this.componentData.yAxis.length === 1 &&
                this.componentData.yAxis.push(this.componentData.yAxis[0])
            }
          } else {
            this.componentData.seriesYAxisIndexList.forEach((item, i) => {
              data.valueList[i] &&
                data.valueList[i].value &&
                data.valueList[i].value[0] &&
                (this.yAxisUnit[item] = data.valueList[i].value[0].unit || '')
            })
          }

          this.seriesTypeList = this.componentData.seriesTypeList
          this.seriesYAxisIndexList = this.componentData.seriesYAxisIndexList
          this.$emit( 'changeSeriesTypeList', this.componentData.seriesTypeList)
          this.$emit(
            'changeSeriesYAxisIndexList',
            this.componentData.seriesYAxisIndexList
          )
          this.$emit( 'changeColYAxis', this.componentData.yAxis)

          data.valueList.forEach((item) => {
            tmpUnit =
              item.value && item.value[0] ? item.value[0].unit || '' : ''
            this.unit[item.name] = tmpUnit
            this.yAxisUnit.indexOf(tmpUnit) === -1 &&
              this.yAxisUnit.push(tmpUnit)
            this.dataUnit.push(tmpUnit)
          })

          if (!Array.isArray(commonLineData.yAxis)) {
            commonLineData.yAxis = [commonLineData.yAxis]
          }

          let yAxisUnit = this.yAxisUnit
          commonLineData.yAxis.forEach((item, i) => {
            commonLineData.yAxis[i].axisLabel = {
              formatter: '{value}' + (yAxisUnit[i] || ''),
            }
          })

          let seriesUnit = this.unit
          commonLineData.tooltip.formatter = function (param) {
            let str = ''
            if (param.length > 0) {
              str = param[0].axisValue + '<br/>'
            }
            for (let i = 0; i < param.length; i++) {
              if (
                param[i].value === ' ' ||
                (!param[i].value && param[i].value !== 0)
              ) {
                str = str + param[i].marker + param[i].seriesName + '<br/>'
              } else {
                str =
                  str +
                  param[i].marker +
                  param[i].seriesName +
                  ' : ' +
                  param[i].value +
                  (seriesUnit[param[i].seriesName] || '') +
                  '<br/>'
              }
            }
            return str
          }
          commonLineData.xAxis[0].data = xData
          commonLineData.series = yData.map((item, i) => ({
            type: this.seriesTypeList[i] ? 'bar' : 'line',
            yAxisIndex: +this.seriesYAxisIndexList[i],
            symbol: 'circle',
            symbolSize: 1,
            barMaxWidth: '29',
            showAllSymbol: true,
            name: item.name,
            itemStyle: {
              normal: {
                areaStyle: {
                  opacity: 0,
                },
              },
            },
            data: item.value.map((item) => {
              return {
                value: item.data,
              }
            }),
          }))

          // 运营报表计算详情: 计算资源 - 租户（共享集群）特殊处理: 两柱重叠、CPU线左右顶头展示
          if (this.api && this.api.dsId === '4CNE0650IGDRS00K') {
            commonLineData.xAxis[1] = {
              data: commonLineData.xAxis[0].data,
              type: 'category',
              axisLine: { show: false },
              axisTick: { show: false },
              axisLabel: { show: false },
              splitArea: { show: false },
              splitLine: { show: false },
            }
            commonLineData.series[1].zlevel = -1
            commonLineData.series[1].xAxisIndex = 1
            commonLineData.series[1].yAxisIndex = 0
            commonLineData.series[2].lineStyle = {
              width: 0,
              opacity: 0,
            }

            if (data.valueList.length === 3) {
              try {
                let mlData = data.valueList[2].value
                let markLineObj = {
                  symbol: 'none', //去掉箭头
                  itemStyle: {
                    normal: {
                      lineStyle: {
                        type: 'solid',
                        color: '#419EFF',
                        opacity: 1,
                        width: 2,
                      },
                      label: {
                        formatter: '',
                      },
                    },
                    emphasis: {
                      lineStyle: {
                        type: 'solid',
                        color: '#419EFF',
                        opacity: 1,
                        width: 2,
                      },
                    },
                  },
                  data: [{ yAxis: mlData[0].data }],
                }
                commonLineData.series[2].markLine = markLineObj
              } catch (e) {}
            }
          }

          commonLineData.legend.data = yData.map((item) => item.name)
        }
        this.chartLoading = false
        if (!this.isDataReady) {
          this.isDataReady = true
          this.$emit( 'dataReady')
        }
      }
      if (!this.api || !this.api.reqUrl) {
        let data = {
          valueList: [
            //纵轴数据
            {
              //每一项是每条线的数据
              name: '示例数据1', //右上角tooltip展示和每条线鼠标悬浮展示字
              value: [
                {
                  data: 120, //线上点高度
                  name: '周一', //对应横坐标label
                  unit: '个',
                },
                {
                  data: 130,
                  name: '周二',
                  unit: '个',
                },
                {
                  data: 140,
                  name: '周三',
                  unit: '个',
                },
                {
                  data: 120,
                  name: '周四',
                  unit: '个',
                },
                {
                  data: 100,
                  name: '周五',
                  unit: '个',
                },
                {
                  data: 80,
                  name: '周六',
                  unit: '个',
                },
                {
                  data: 120,
                  name: '周日',
                  unit: '个',
                },
              ],
            },
            {
              name: '示例数据2',
              value: [
                {
                  data: 240,
                  name: '周一',
                  unit: '个',
                },
                {
                  data: 40,
                  name: '周二',
                  unit: '个',
                },
                {
                  data: 160,
                  name: '周三',
                  unit: '个',
                },
                {
                  data: 130,
                  name: '周四',
                  unit: '个',
                },
                {
                  data: 250,
                  name: '周五',
                  unit: '个',
                },
                {
                  data: 300,
                  name: '周六',
                  unit: '个',
                },
                {
                  data: 150,
                  name: '周日',
                  unit: '个',
                },
              ],
            },
          ],
        }
        parseLineData(data)
        if (callback) {
          callback()
        }
      } else {
        if (this.mixinParam) {
          // 判断混参关键属性是否配置
          // 配置
          if (this.mixinParam.hasOwnProperty('mixinParamKeyword')) {
            // 关键属性存在, 判断关键属性对应的值是否为空
            // 有值则调用数据源接口查询数据
            if (this.mixinParam[this.mixinParam['mixinParamKeyword']]) {
              this.doRequest(parseLineData, callback)
            }
            // 空则直接清空图表
            else {
              parseLineData({})
              let interval = setInterval(() => {
                if (this.$refs.lineChart) {
                  clearInterval(interval)

                  this.$refs.lineChart.resize()
                }
              })
            }
          }
          // 未配置, 按原流程处理
          else {
            this.doRequest(parseLineData, callback)
          }
        } else {
          this.lineLoading = false
        }
      }
    },
    doRequest(parseLineData, callback) {
      nt.doRequest({
        method: 'post',
        uri: '/paas/chart-layout/v1/compdsconfig/testCompDSConfig',
        data: parseApi({
          api: this.api,
          time: this.time,
          mixinParam: this.mixinParam,
        }),
        onSuccess: (resp) => {
          let data = resp.data.content.content
          data = data || {}
          // if (!data || JSON.stringify(data) === '{}') {
          //   this.chartLoading = false
          //   return
          // }
          parseLineData(data)
          if (callback) {
            callback()
          }
        },
        onError: () => {
          parseLineData({})
          if (callback) {
            callback()
          }
          this.chartLoading = false
        },
      })
    },
    changeStyle() {
      let commonLineData = this.commonLineData
      let componentData = this.componentData
      commonLineData.xAxis[0].show = componentData.xAxis.show
      commonLineData.xAxis[0].axisLine.show = componentData.xAxis.axis.show
      if (componentData.seriesTypeList.some((item) => item)) {
        commonLineData.xAxis[0].axisLabel.interval = 0
      } else {
        commonLineData.xAxis[0].axisLabel.interval = 'auto'
      }
      commonLineData.xAxis[0].axisLabel.rotate = componentData.xRotate
      commonLineData.yAxis[0].axisLabel.rotate = componentData.yRotate
      commonLineData.yAxis[0].minInterval = componentData.splitInt ? 1 : 0
      commonLineData.grid = componentData.grid
      commonLineData.color = componentData.color
      for (let key in componentData.legend) {
        commonLineData.legend[key] = componentData.legend[key]
      }
      let areaStyle = componentData.series[0].areaStyle
      let lineType = componentData.series[0].lineType

      // 折线默认坐标轴两边不留白
      let boundaryGap = false
      commonLineData.series.forEach((item, i) => {
        // 如果是柱状+折线组合图，则两边留白
        if (this.componentData.seriesTypeList[i]) {
          boundaryGap = true
        }
        item.connectNulls = componentData.series[0].connectNulls || false
        if (componentData.series[0].connectNulls) {
          let valueList = item.data.map((dataItem) => dataItem.value)
          let length = valueList.length
          let startIndex = valueList.findIndex((item) => item !== undefined)
          valueList.reverse()
          let endIndex =
            length - valueList.findIndex((item) => item !== undefined) - 1
          valueList.reverse()
          if (startIndex !== 0) item.data[0] = valueList[startIndex]
          if (endIndex !== length - 1)
            item.data[length - 1] = valueList[endIndex]
        }
        item['type'] = this.componentData.seriesTypeList[i] ? 'bar' : 'line'
        item['yAxisIndex'] = this.componentData.seriesYAxisIndexList[i] // 曲线所在Y轴索引, Y1轴索引为0
        if (!lineType) {
          item.smooth = false
          item.step = false
        } else {
          if (lineType == 'smooth') {
            item.smooth = true
            item.step = false
          } else if (lineType == 'step') {
            item.smooth = false
            item.step = true
          }
        }
        item.itemStyle.normal.areaStyle.opacity = areaStyle ? 0.1 : 0
      })
      commonLineData.xAxis[0].boundaryGap = boundaryGap
      // 考虑多Y轴场景
      if (!Array.isArray(componentData.yAxis)) {
        componentData.yAxis = [componentData.yAxis]
      }
      if (!componentData.yAxis[0]) {
        componentData.yAxis[0] = {
          nameUnit: false,
          show: true,
          axisLabel: {},
        }
        commonLineData.yAxis[0].axisLabel.rotate = componentData.yRotate
      }
      // 设置Y轴单位
      let yAxisUnit = []
      // Y1轴, 索引0
      let yIndex0 = this.componentData.seriesYAxisIndexList.indexOf(0)
      if (yIndex0 > -1) {
        yAxisUnit[0] = this.dataUnit[yIndex0]
      }
      // Y2轴, 索引1
      let yIndex1 = this.componentData.seriesYAxisIndexList.indexOf(1)
      if (yIndex1 > -1) {
        yAxisUnit[1] = this.dataUnit[yIndex1]
      }
      this.yAxisUnit = JSON.parse(JSON.stringify(yAxisUnit))

      componentData.yAxis.forEach((item, i) => {
        if (!commonLineData.yAxis[i]) {
          commonLineData.yAxis[i] = JSON.parse(JSON.stringify(this.yAxisObj))
        }
        commonLineData.yAxis[i].show = componentData.yAxis[i].show
        if (!componentData.yAxis[i].nameUnit) {
          commonLineData.yAxis[i].axisLabel = {
            formatter: (params) => {
              return params + (yAxisUnit[i] || '')
            },
            rotate: componentData.yRotate,
          }
          commonLineData.yAxis[i].name = null
        } else {
          commonLineData.yAxis[i].name = yAxisUnit[i]
            ? '单位：' + yAxisUnit[i] || ''
            : ''
          commonLineData.yAxis[i].axisLabel = {
            formatter: '{value}',
            rotate: componentData.yRotate,
          }
        }
      })
      if (componentData.yAxis[0].autoMin) {
        commonLineData.yAxis[0].min = (value) => {
          let cha = value.max - value.min
          let min = cha / 10
          return value.min - min < 0 ? 0 : Math.floor(value.min - min)
        }
      } else {
        commonLineData.yAxis[0].min = undefined
      }
      this.commonLineOption = _.cloneDeep(commonLineData)
      if (componentData.code) {
        //给开发人员测试的，怕忘记删，生产环境就不打印了
        process.env.NODE_ENV === 'development' &&
          console.log(this.mainTitle + ' 混入前option', commonLineData)
        this.commonLineOption = mixinOption(
          this.commonLineOption,
          componentData.code
        )
        process.env.NODE_ENV === 'development' &&
          console.log(this.mainTitle + ' 混入后option', this.commonLineOption)
      }

      if (this.$refs.lineChart) {
        this.$nextTick().then(this.$refs.lineChart.resize)
        // this.$refs.lineChart.resize()
      }
    },
    getItemData(e) {
      let event = e.event.event

      this.showTip = true
      this.lineContent = `${e.name} <br/> ${e.seriesName}： ${e.value} ${
        this.unit[e.seriesName] || ''
      }`
      let tipBox = $(event.target)
        .parentsUntil('.line-row')
        .siblings('.tip-box')
      this.$nextTick(() => {
        this.$refs.lineChart.dispatchAction({
          type: 'hideTip',
        })
        tipBox.css({
          left:
            e.event.offsetX > $(event.target).width() / 2
              ? e.event.offsetX - tipBox.width() - 20
              : e.event.offsetX + 20,
          top: e.event.offsetY - 15,
        })
      })
      if (this.timer) {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(() => (this.showTip = false), 3000)
    },
  },
  created() {
    this.isDataReady = false
    this.getCommonLineData(this.changeStyle)
    if (this.interval) {
      this.comInterval = setInterval(() => {
        this.getCommonLineData(this.changeStyle)
      }, this.interval * 1000)
    }
  },
  beforeDestroy() {
    clearInterval(this.comInterval)
  },
  emits: [
    'changeSeriesTypeList',
    'changeSeriesYAxisIndexList',
    'changeColYAxis',
    'dataReady',
  ],
}
</script>

<style scoped>
.tip-box {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 9999;
  white-space: nowrap;
  background-color: rgba(50, 50, 50, 0.7);
  border-radius: 4px;
  color: rgb(255, 255, 255);
  font: 14px / 21px 'Microsoft YaHei';
  padding: 5px;
  text-align: left;
  pointer-events: none;
}
.asset-time-title {
  font-size: 14px;
  color: #6d7c8b;
  font-weight: bold;
  position: absolute;
  background: #fff;
  width: 100%;
  top: -38px;
  left: 0px;
}
.line-row {
  width: 100%;
  height: 100%;
}
.chart-box {
  width: 100%;
  height: 100%;
  position: relative;
}
.operatorBtn {
  position: absolute;
  top: -50px;
  right: 20px;
  width: 30px;
  height: 20px;
  font-size: 14px;
  font-family: PingFangSC-Medium;
  color: #419eff;
  line-height: 20px;
}
</style>
